package org.trimard;

import java.util.Arrays;

import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.graphics.Color;
import android.graphics.Typeface;
import android.preference.PreferenceManager;
import android.widget.LinearLayout;

public class SailChartView implements OnSharedPreferenceChangeListener
{
	private static final double MIN_SURFACE=3.0;
	private static final double MAX_SURFACE=12.0;

	private static final double STEP_SURFACE=0.3;

	private static final int NOVICE_COLOR=0xff0000ff;
	private static final int INTERMEDIATE_COLOR=0xff0000f6;
	private static final int ADVANCE_COLOR=0xff0000e9;

	private static final int[] colors = new int[] { ADVANCE_COLOR, INTERMEDIATE_COLOR, NOVICE_COLOR, INTERMEDIATE_COLOR, ADVANCE_COLOR, Color.BLACK };

	private final SharedPreferences sharedPrefs;
	private final LinearLayout linearLayout;
	private final Context context;

	public SailChartView(Context context, LinearLayout linearLayout)
	{
        this.context=context;
		this.linearLayout=linearLayout;
		sharedPrefs=PreferenceManager.getDefaultSharedPreferences(context);
		sharedPrefs.registerOnSharedPreferenceChangeListener(this);
		redraw();
	}

	protected void redraw()
	{
		GraphicalView createView=createView();
		linearLayout.removeAllViews();
		linearLayout.addView(createView);
	}

	protected void destroy()
	{
		sharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
	}


	/**
	 * Builds an XY multiple series renderer.
	 *
	 * @param colors the series rendering colors
	 * @param styles the series point styles
	 * @return the XY multiple series renderers
	 */
	protected XYMultipleSeriesRenderer buildRenderer(int[] colors, PointStyle[] styles) {
		XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
		renderer.setAxisTitleTextSize(16);
		renderer.setChartTitleTextSize(20);
		renderer.setLabelsTextSize(15);
		renderer.setLegendTextSize(15);
		renderer.setPointSize(5f);
		renderer.setMargins(new int[] { 20, 30, 65, 0 });
		int length = colors.length;
		for (int i = 0; i < length; i++) {
			XYSeriesRenderer r = new XYSeriesRenderer();
			r.setColor(colors[i]);
			r.setPointStyle(styles[i]);
			renderer.addSeriesRenderer(r);
		}
		return renderer;
	}

	/**
	 * Sets a few of the series renderer settings.
	 *
	 * @param renderer the renderer to set the properties to
	 * @param title the chart title
	 * @param xTitle the title for the X axis
	 * @param yTitle the title for the Y axis
	 * @param xMin the minimum value on the X axis
	 * @param xMax the maximum value on the X axis
	 * @param yMin the minimum value on the Y axis
	 * @param yMax the maximum value on the Y axis
	 * @param axesColor the axes color
	 * @param labelsColor the labels color
	 */
	protected void setChartSettings(XYMultipleSeriesRenderer renderer, String title, String xTitle,
			String yTitle, double xMin, double xMax, double yMin, double yMax, int axesColor,
			int labelsColor) {
		renderer.setChartTitle(title);
		renderer.setXTitle(xTitle);
		renderer.setYTitle(yTitle);
		renderer.setXAxisMin(xMin);
		renderer.setXAxisMax(xMax);
		renderer.setYAxisMin(yMin);
		renderer.setYAxisMax(yMax);
		renderer.setPanLimits(new double []{xMin, xMax, yMin, yMax});
		renderer.setAxesColor(axesColor);
		renderer.setLabelsColor(labelsColor);
	}

	/**
	 * Builds a bar multiple series dataset using the provided values.
	 *
	 * @param titles the series titles
	 * @param values the values
	 * @return the XY multiple bar dataset
	 */
	protected XYMultipleSeriesDataset buildBarDataset() {
		XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
		XYSeries minIntermediateSeries = new XYSeries("MinIntermediateSail");
		XYSeries maxIntermediateSeries = new XYSeries("MaxIntermediateSail");
		XYSeries minNoviceSeries = new XYSeries("MinNoviceSail");
		XYSeries maxNoviceSeries = new XYSeries("MaxNoviceSail");
		XYSeries minAdvanceSeries = new XYSeries("MinAdvanceSail");
		XYSeries maxAdvanceSeries = new XYSeries("MaxAdvanceSail");
		for (double surface = MIN_SURFACE; surface < MAX_SURFACE; surface+=STEP_SURFACE)
		{
			add(minNoviceSeries, surface, Preset.NOVICE.lower);
			add(maxNoviceSeries, surface, Preset.NOVICE.upper);
			add(minIntermediateSeries, surface, Preset.INTERMEDIATE.lower);
			add(maxIntermediateSeries, surface, Preset.INTERMEDIATE.upper);
			add(minAdvanceSeries, surface, Preset.ADVANCE.lower);
			add(maxAdvanceSeries, surface, Preset.ADVANCE.upper);
		}
		dataset.addSeries(maxNoviceSeries);
		dataset.addSeries(maxIntermediateSeries);
		dataset.addSeries(maxAdvanceSeries);
		dataset.addSeries(minNoviceSeries);
		dataset.addSeries(minIntermediateSeries);
		dataset.addSeries(minAdvanceSeries);
		return dataset;
	}

	private void add(XYSeries series, double surface, double ratio)
	{
		double weight=Double.parseDouble(getWeight());
		double minKnots=(weight+20.0)*ratio/surface;
		series.add(surface, minKnots);
	}

	protected String getWeight()
	{
		return sharedPrefs.getString(PreferenceConstant.WEIGHT_KEY, PreferenceConstant.WEIGHT_DEFAULT);
	}

    private GraphicalView createView()
	{
    	PointStyle[] styles = new PointStyle[colors.length];
    	Arrays.fill(styles, PointStyle.POINT);
    	XYMultipleSeriesRenderer renderer = buildRenderer(colors, styles);
    	setChartSettings(renderer, getWeight() + " Kg", "Surface", "Wind (knots)", MIN_SURFACE, MAX_SURFACE, 0, 60, Color.GRAY, Color.LTGRAY);
    	renderer.setXLabels(12);
    	renderer.setYLabels(10);
    	renderer.setChartTitleTextSize(20);
    	renderer.setTextTypeface("sans_serif", Typeface.BOLD);
    	renderer.setChartValuesTextSize(10f);
    	renderer.setLabelsTextSize(14f);
    	renderer.setAxisTitleTextSize(15);
    	renderer.setShowLegend(false);
    	for (int i = 0; i < renderer.getSeriesRendererCount(); i++)
    	{
    		XYSeriesRenderer seriesRenderer = (XYSeriesRenderer) renderer.getSeriesRendererAt(i);
    		seriesRenderer.setFillBelowLine(true);
    		seriesRenderer.setFillBelowLineColor(colors[i]);
    	}
    	return ChartFactory.getLineChartView(context, buildBarDataset(), renderer);

	}

	@Override
	public void onSharedPreferenceChanged(SharedPreferences sharedpreferences, String s)
	{
		if(s.equals(PreferenceConstant.WEIGHT_KEY))
			redraw();
	}
}
